/*package com.utils.spring;

import java.io.IOException;
import java.util.Date;
import java.util.Enumeration;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.http.MediaType;

import com.google.common.collect.Maps;
import com.kyhd.lib.util.Util;
import com.kyhd.toutiao.controller.model.ReqCtx;
import com.kyhd.toutiao.redis.CodeRedis;
import com.kyhd.toutiao.util.DateUtil;
import com.kyhd.toutiao.util.EncrypUtil;
import com.kyhd.toutiao.util.InitConst;
import com.kyhd.toutiao.util.ReqCtxUtil;

import lombok.extern.slf4j.Slf4j;


 * 服务器的一个url请求拦截规则
 * 
 * （1）判断是否包含id,times,sign参数，如果不含有返回错误码。
 * 
 * （2）判断服务器接到请求的时间和参数中的时间戳是否相差很长一段时间（时间自定义30s），如果超过则说明该
 *  url已经过期（如果url被盗，他改变了时间戳，但是会导致sign签名不相等）。
 * 
 * （3）判断id是否有效，根据请求过来的id，查询redis缓存中的token，如果获取不到这说明该id未登陆/token过期。
 * 
 * （4）根据用户请求的url参数，服务器端按照同样的规则生成sign签名，对比签名看是否相等，相等则放行。
 * （生成规则：将id,times,sign三个参数根据字典排序，拼接上uri,然后再用MD5加密)
 * （自然url签名也无法100%保证其安全，也可以通过公钥AES对数据和url加密，但这样如果无法确保公钥丢失，所以签名只是很大程 度上保证安全）。
 * 
 * （5）此url拦截只需对获取身份认证的url放行（如登陆url，获取验证码，启动app应用），剩余所有的url都需拦截。
 * 
 * （6）请求通过后，如果请求参数中有data参数，则对data参数值进行解密，并存放到threadlocal中
 *  （这样在controlle中r就不用再对请求数据进行解密操作，有其他参数的话再自行解密）
 
@Order(2)
@Slf4j
@WebFilter(filterName = "userFilter1", urlPatterns = {
		
        "/tt/api/user/getuser",
        "/tt/api/user/updateimage",
        "/tt/api/user/updatesex",
        "/tt/api/user/updatenick",
        "/tt/api/user/updatebirthday",
        "/tt/api/user/bindphone",
        "/tt/api/user/quit",
        "/tt/api/user/getmsg",
        "/tt/api/user/bindwechat",
        
		"/tt/api/task/depsitHistory",
		"/tt/api/task/balance",
		"/tt/api/task/myTaskList",
		"/tt/api/task/siginList",
		"/tt/api/task/sigin",
		"/tt/api/task/once",
		"/tt/api/task/done_day",
		"/tt/api/task/day",
		"/tt/api/task/hour",
		"/tt/api/task/visit",
		"/tt/api/task/share",
		"/tt/api/task/wall",
		"/tt/api/task/done_wall",
		"/tt/api/task/wallList",

		"/tt/api/mentor/*",
		"/tt/api/share/apprentice",
		"/tt/api/share/awaken",
//		"/tt/api/question/*",
		"/tt/api/cash/*"

        })
public class UserFilter implements Filter {

	@Autowired
	CodeRedis codeRedis;

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {

	}

	@Override
	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
			throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) servletRequest;
		HttpServletResponse response = (HttpServletResponse) servletResponse;

		try {
			Map<String, String> signMap = Maps.newHashMap();
			String uri = request.getRequestURI();
			
			Enumeration<?> pNames = request.getParameterNames();
			Map<String, String> params = Maps.newHashMap();
//		    StringBuilder parameters = new StringBuilder();
			while (pNames.hasMoreElements()) {
				String pName = (String) pNames.nextElement();
				String pValue = request.getParameter(pName);
//		        parameters.append(pName + ":" + pValue + " ");
				params.put(pName, pValue);
				//只有uuid参数，times参数和token参数参与字典排序和加密过程
				if("uuid".equals(pName)||"times".equals(pName)) {
					signMap.put(pName, pValue);
				}
			}
			
			//更新图像时，将参数放在header，然后从header里取
			Enumeration<?> hNames = request.getHeaderNames();
//		    StringBuilder headers = new StringBuilder();
			while (hNames.hasMoreElements()) {
				String hName = (String) hNames.nextElement();
				String hValue = request.getHeader(hName);
//				headers.append(hName + ":" + hValue + " || ");
				params.put(hName, hValue);
				//只有uuid参数，times参数和token参数参与字典排序和加密过程
				if("uuid".equals(hName)||"times".equals(hName)) {
					signMap.put(hName, hValue);
				}
			}
//			log.info("Parameter:{"+parameters.toString()+"}, "+"Headers:{"+headers.toString()+"}");
			
			if (!params.containsKey("uuid")) {
				response.setContentType(MediaType.TEXT_PLAIN.toString());
				response.setStatus(403);
				response.getWriter().write("Not login");
			} else if (!params.containsKey("times")) {
				response.setContentType(MediaType.TEXT_PLAIN.toString());
				response.setStatus(403);
				response.getWriter().write("Not login");
			} else if (!params.containsKey("sign")) {
				response.setContentType(MediaType.TEXT_PLAIN.toString());
				response.setStatus(403);
				response.getWriter().write("Not login");
			}else {
				long nowTimes = DateUtil.getMills(new Date(), null);
				if (((nowTimes/1000) - Long.valueOf(params.get("times"))) > InitConst.URL_TIMEOUT
						||(Long.valueOf(params.get("times")) - (nowTimes/1000)) > InitConst.URL_TIMEOUT) {
					response.setContentType(MediaType.TEXT_PLAIN.toString());
					response.setStatus(403);
					response.getWriter().write("Not login");
				}else {
					Object token = this.codeRedis.getValue(params.get("uuid"));
					if (token == null || "".equals(token.toString().trim())) {
						response.setContentType(MediaType.TEXT_PLAIN.toString());
						response.setStatus(403);
						response.getWriter().write("Not login");
					}else {
						signMap.put("token", token.toString());

						String nowSign = EncrypUtil.createSign(uri,signMap, true);
						if (!nowSign.equals(params.get("sign"))) {
							response.setContentType(MediaType.TEXT_PLAIN.toString());
							response.setStatus(403);
							response.getWriter().write("Not login");
						}else {
							ReqCtx _ctx = new ReqCtx();
							if (params.containsKey("data")) {
								String data = params.get("data");
								String desData = EncrypUtil.desEncryptByToken(data, token.toString());
								_ctx.setData(desData.trim());
							}

							_ctx.setUuid(params.get("uuid"));
							_ctx.setToken(token.toString());
							log.info("requestContext _ctx:{},uri:{}", _ctx,uri);
							ReqCtxUtil.reqCtx.set(_ctx);
							
							params.clear();
				            filterChain.doFilter(servletRequest, servletResponse);
							ReqCtxUtil.reqCtx.remove();
						}
					}
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
			log.error(Util.getExceptionStackTrace(e));
			ReqCtxUtil.reqCtx.remove();
			// throw e;
		}

	}

	@Override
	public void destroy() {

	}

}
*/